from pydantic import BaseModel
from typing import Any, Callable, Coroutine, Dict, List, Optional, Sequence, Type, Union
from fastapi import Request
from fastapi.datastructures import Default, DefaultPlaceholder
from fastapi.encoders import DictIntStrAny, SetIntStr
from fastapi.params import Depends
from starlette.responses import JSONResponse, Response


class Return(BaseModel):
    """这里是接口返回值"""
    pass


class BaseApi():
    """此下参数为add_api_route中的参数，为方便配置路由设置的"""
    path: str
    response_model: Optional[Type[Any]] = None
    status_code: int = 200
    tags: Optional[List[str]] = None
    summary: Optional[str] = None
    description: Optional[str] = None
    response_description: str = "Successful Response"
    responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None
    deprecated: Optional[bool] = None
    methods: Optional[List[str]] = None
    operation_id: Optional[str] = None
    response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None
    response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None
    response_model_by_alias: bool = True
    response_model_exclude_unset: bool = False
    response_model_exclude_defaults: bool = False
    response_model_exclude_none: bool = False
    include_in_schema: bool = True
    response_class: Union[Type[Response], DefaultPlaceholder] = Default(
        JSONResponse)

    class Return(BaseModel):
        """这里是接口返回值"""
        pass

    @property
    def get_router(self):
        """获取接口router信息"""
        return {
            "path": self.path, "response_model": self.Return,
            "status_code": self.status_code,
            "tags": self.tags,
            "summary": self.summary,
            "description": self.description, "response_description": self.response_description,
            "responses": self.responses,
            "deprecated": self.deprecated,
            "methods": self.methods,
            "operation_id": self.operation_id,
            "response_model_include": self.response_model_include,
            "response_model_exclude": self.response_model_exclude,
            "response_model_by_alias": self.response_model_by_alias,
            "response_model_exclude_unset": self.response_model_exclude_unset,
            "response_model_exclude_defaults": self.response_model_exclude_defaults,
            "response_model_exclude_none": self.response_model_exclude_none,
            "include_in_schema": self.include_in_schema, "response_class": self.response_class
        }

    def api_router(
            self,
            path: str,
            *,
            response_model: Optional[Type[Any]] = None,
            status_code: int = 200,
            tags: Optional[List[str]] = None,
            dependencies: Optional[Sequence[Depends]] = None,
            summary: Optional[str] = None,
            description: Optional[str] = None,
            response_description: str = "Successful Response",
            responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
            deprecated: Optional[bool] = None,
            methods: Optional[List[str]] = None,
            operation_id: Optional[str] = None,
            response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
            response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
            response_model_by_alias: bool = True,
            response_model_exclude_unset: bool = False,
            response_model_exclude_defaults: bool = False,
            response_model_exclude_none: bool = False,
            include_in_schema: bool = True,
            response_class: Union[Type[Response], DefaultPlaceholder] = Default(
                JSONResponse)):
        """"""
        return {
            "path": path,
            "response_model": response_model,
            "status_code": status_code,
            "tags": tags,
            "dependencies": dependencies, "summary": summary,
            "description": description, "response_description": response_description, "responses": responses,
            "deprecated": deprecated,
            "methods": methods,
            "operation_id": operation_id,
            "response_model_include": response_model_include, "response_model_exclude": response_model_exclude,
            "response_model_by_alias": response_model_by_alias,
            "response_model_exclude_unset": response_model_exclude_unset,
            "response_model_exclude_defaults": response_model_exclude_defaults,
            "response_model_exclude_none": response_model_exclude_none,
            "include_in_schema": include_in_schema, "response_class": response_class
        }

    @staticmethod
    def prepare_envrioment(request: Request):
        """请求接口前的环境准备"""
        pass

    def deal(self, **kwargs):
        """处理函数入口"""


def test():
    """测试接口可以配置成功"""
    from fastapi import FastAPI
    import uvicorn
    app = FastAPI()

    ba = BaseApi()
    ba.path = "/verion"
    ba.methods = ["GET"]
    router = ba.get_router
    print(router)

    app.add_api_route(dependencies=[Depends(ba.prepare_envrioment)], endpoint=ba.deal, **router)
    uvicorn.run(app, host='0.0.0.0', access_log=True, use_colors=True)


if __name__ == '__main__':
    test()